<?php

namespace app\portal\controller;

use app\admin\model\Paper;
use app\admin\model\Question;
use app\base\model\User;
use app\common\controller\PortalBase;
use think\Request;
use think\Db;


class Room extends PortalBase {
  protected $modelRoom, $modelUser, $modelPaper, $modelQuestion;

  public function __construct(Request $request = NULL) {
    parent::__construct($request);
    $this->modelRoom = new \app\admin\model\Room();
    $this->modelUser = new User();
    $this->modelPaper = new Paper();
    $this->modelQuestion = new Question();
    config('system.portal_name', '实验室安全考试系统');
  }

  public function _initialize() {
    parent::_initialize();

  }

  public function view() {
    $id = input('id/d', 0);
    $room = ($id > 0) ? $this->modelRoom->find($id) : [];
    $map = ['room_id' => $id,
            'uid'     => $this->uid];
    $paper = ($id > 0) ? $this->modelPaper->where($map)->find() : [];

    if (!$room or !$paper) $this->error(lang('data empty'));
    //计算时间
    $nowTimestamp = time();
    $startTime = $room['start_time'];
    $endTime = $room['end_time'];
    if ($room['status'] != 1) {
      $this->error('考试尚未开始或者已经结束');
    }
    if ($paper['status'] == 1) {
      $this->error('考卷已经提交，不能修改');
    }

    $questions = json_decode($paper['questions'], TRUE);

    $cursorMax = count($questions);//最大游标
    $cursors = json_encode(range(1, $cursorMax));
    //计算结束时间
    $endTimestamp = strtotime($room['end_time']);
    $overplusTime = $endTimestamp - $nowTimestamp;
    if ($overplusTime > 0) {
      $minute = floor($overplusTime / 60);
      $second = $overplusTime % 60;
    } else {
      $minute = $second = 0;
    }
    $examFinish = $overplusTime <= 0 ? 1 : 0;

    cmf_log('开始考试', $id, date('Y-m-d H:i'));

    return view('', [
      'cursorMax'    => $cursorMax,
      'room'         => $room,
      'cursor'       => $paper['cursor'],
      'cursors'      => $cursors,
      'paperId'      => $paper['id'],
      'nowTime'      => date('H:i:s', $nowTimestamp),
      'nowTimestamp' => $nowTimestamp,
      'minute'       => $minute,
      'second'       => $second,
      'examFinish'   => $examFinish,
      'passScore'    => $room['pass_score'],
      'commitment'   => cmf_get_commitment()['content'],
    ]);
  }

  public function getPaperQuestions() {
    $paperId = input('paper_id', 0);
    $cursor = input('cursor/d', 0);
    $paper = ($paperId > 0) ? $this->modelPaper->find($paperId) : NULL;
    if (!$paper)
      $this->error(lang('paper empty'));
    if ($paper['uid'] != $this->uid)
      $this->error('错误，该考卷与当前考试人不符合' . $this->uid . $paper['uid'] . $paperId);
    //返回所有问题的数据
    $paperQuestionIDs = json_decode($paper['questions'], TRUE);
    $paperQuestions = $this->modelQuestion->where('id', 'in', $paperQuestionIDs)->column('content,answers', 'id');
    //返回所有问题的答案
    $paperAnswers = json_decode($paper['answers'], TRUE);
    //返回所有的标记
    $paperSign = json_decode($paper['sign'], TRUE);
    $active = -1;
    if ($paperAnswers) {
      $active = $paperAnswers[ $cursor ];
    } else {
      $paperAnswers = [];
    }
    //返回数据
    $data = [
      'question'         => $paperQuestions[0],
      'paperQuestionIDs' => $paperQuestionIDs,
      'paperQuestions'   => $paperQuestions,
      'paperSign'        => $paperSign ? $paperSign : [],
      'active'           => $active,
      'paperAnswers'     => $paperAnswers,
    ];
    $this->result($data, 1);
  }

  /**
   * @throws \think\db\exception\DataNotFoundException
   * @throws \think\db\exception\ModelNotFoundException
   * @throws \think\exception\DbException
   * 提交答案
   */

  public function doAnswer() {
    $paperId = input('paper_id', 0);
    $cursor = input('cursor/d', 0);
    $answer = input('answer/d', 0);
    $paper = ($paperId > 0) ? $this->modelPaper->find($paperId) : NULL;
    if (!$paper)
      $this->error(lang('paper empty'));
    if ($paper['uid'] != $this->uid)
      $this->error('错误，该考卷与当前考试人不符合');
    if ($paper['status'] != 0)
      $this->error('错误，试卷已经完成了，不能提交答案');
    //
    $room = $this->modelRoom->cache(TRUE)->find($paper['room_id']);
    $nowTimestamp = time();
    if ($nowTimestamp > strtotime($room['end_time'])) {
      $this->finish($paperId);

      return FALSE;
    }
    $answers = json_decode($paper['answers'], TRUE);
    $answers[ $cursor ] = $answer;
    $data = [
      'answers' => json_encode($answers),
      'cursor'  => $cursor,
    ];
    $r = $this->modelPaper->save($data, ['id' => $paperId]);
    if ($r === FALSE) $this->error(lang('error') . $this->modelPaper->getError());
    $this->success();
  }

  public function signQuestion() {
    $paperId = input('paper_id', 0);
    $cursor = input('cursor/d', 0);
    $paper = ($paperId > 0) ? $this->modelPaper->find($paperId) : NULL;
    if (!$paper)
      $this->error(lang('paper empty'));
    if ($paper['uid'] != $this->uid)
      $this->error('错误，该考卷与当前考试人不符合');
    $sign = json_decode($paper['sign'], TRUE);
    if (!$sign) {
      $sign[ $cursor ] = 1;
    } else {
      $sign[ $cursor ] = !$sign[ $cursor ];
    }

    $data = [
      'sign' => json_encode($sign),
    ];
    $r = $this->modelPaper->save($data, ['id' => $paperId]);
    if ($r !== FALSE)
      $this->success();
    $this->error();
  }

  /**
   * @param int $paperId 考卷id
   */

  public function finish($paperId = 0) {
    $paperId = input('paper_id', $paperId);
    $paper = ($paperId > 0) ? $this->modelPaper->find($paperId) : NULL;
    if (!$paper)
      $this->error(lang('paper empty'));
    if ($paper['uid'] != $this->uid)
      $this->error('错误，该考卷与当前考试人不符合');
    if ($paper['status'] != 0)
      $this->error('错误，试卷已经完成了，不能再次提交');
    $room = $this->modelRoom->find($paper['room_id']);
    $qConfig = json_decode($room['q_config'], TRUE);
    $questions = json_decode($paper['questions'], TRUE);
    $answers = json_decode($paper['answers'], TRUE);

    $qInfo = $this->modelQuestion->getQuestion($questions);
    $rightCount = 0;
    $score = 0;
    foreach ($questions as $key => $qid) {
      if ($qInfo[ $qid ]['right'] === $answers[ $key ]) {
        $type = $qInfo[ $qid ]['type'];
        $rightCount += 1;
        $score += $qConfig[ $type ]['score'];
      }
    }
    //交卷
    $data = [
      'status'      => 1,
      'right_count' => $rightCount,
      'score'       => $score,
    ];
    $userData = [
      'exam_score' => $score,
      'exam_times' => Db::raw('exam_times+1'),
    ];
    $roomData = [
      'examinee_count' => Db::raw('examinee_count+1'),
    ];

    //事务
    $this->modelPaper->startTrans();
    try {
      $r1 = $this->modelPaper->save($data, ['id' => $paperId]);
      $r2 = $this->modelUser->save($userData, ['id' => $this->uid]);
      $r3 = $this->modelRoom->save($roomData, ['id' => $paper['room_id']]);
      if (!$r1 || !$r2 || !$r3)
        exception(lang('error') . $this->modelPaper->getLastSql());

      $this->modelPaper->commit();
    } catch (\Exception $e) {
      $this->modelPaper->rollback();
      $this->error($e->getMessage());
    }
    //
    $returnData = ['score'       => (int)$score,
                   'right_count' => $rightCount];
    cmf_log('完成考试', $paperId, '考场ID' . ['room_id']);
    $this->success('您的得分' . $score, NULL, $returnData);
  }

  public function commitment() {
    $paperId = input('paper_id', 0);
    $paper = ($paperId > 0) ? $this->modelPaper->find($paperId) : NULL;
    if (!$paper)
      $this->error(lang('paper empty'));
    if ($paper['uid'] != $this->uid)
      $this->error('错误，该考卷与当前考试人不符合');
    if ($paper['status'] != 1)
      $this->error('错误，试卷尚未完成，不能签订承诺书');
    $data = [
      'commitment' => 1,
    ];
    $userData = [
      'commitment'      => 1,
      'commitment_time' => date('Y-m-d H:i:s'),
      'is_pass'         => 1,
    ];
    //
    $this->modelPaper->startTrans();
    try {
      $r1 = $this->modelPaper->save($data, ['id' => $paperId]);
      $r2 = $this->modelUser->save($userData, ['id' => $this->uid]);
      if (!$r1 || !$r2)
        exception($this->modelPaper->getError());

      $this->modelPaper->commit();
    } catch (\Exception $e) {
      $this->modelPaper->rollback();
      $this->error($e->getMessage());
    }
    $this->success(lang('success'), 'index/index');
  }
}
